extends & type narrowing


Posted by TempuraEngineer on 2023-05-08

目錄


type narrowing

type narrowing指的是盡可能地將型別的範圍縮小,這可以利於debug

例如'apple'、'tempura'、'Monday'、'Sunday'都是string,但是只有最後兩個是一週中的日子

假設有個function接收一個字串,並判斷其是不是週末字串

正常的情況下,不該傳遞一個不是週一(到日)的字串給isWeekend,因為那樣的話一定會得到false

所以我們可以直接將day的型別限縮到只有Weekday,這樣當不小心傳到Fruit字串的話,在開發時就會發現了

enum Weekday {
    MON = 'Monday',
    TUE = 'Tuesday',
    WED = 'Wednesday',
    THU = 'Thursday',
    FRI = 'Friday',
    SAT = 'Staturday',
    SUN = 'Sunday',
}

const isWeekend = (day: Weekday) => {
    if([Weekday.SAT, Weekday.SUN].includes(day)){
        return true;
    }

    return false;
}

除了以上的方式以外,type guard、type predicate,這篇要介紹的extends,也都是type narrowing的方法


extends

extends不只能用於擴展interface,還可以限縮型別

使用泛型時,可以配合extends來限縮型別範圍,這樣可以讓程式碼保持適中的彈性

// 檢查字串是不是物件的key
export const isKeyOfObject =
  <T extends object>(enumObject: T) =>
  (value: string): value is Extract<keyof T, string> =>
    value in enumObject;
// 檢查字串是不是物件的value
const isValueOfObject = <T extends object>(enumObj: T) => {
    return (str:unknown):str is T => {
        return Object.values(enumObj).includes(str);
    }
}

// 檢查字串是不是物件的value的小寫化
const isObjectLowerCaseValue = <T extends object>(enumObj: T) => {
    return (str: unknown):str is Lowercase<Extract<T[keyof T], string>> => {
        return Object.values(enumObj).map((i) => i.toLowerCase()).includes(str);
    }
}
// 物件轉陣列
export const objectToArray = <T extends object>(object: T) => {
  const res: T[keyof T][] = [];
  const isObjKey = isKeyOfEnum(object);

  Object.keys(object).forEach((key) => {
    if (isObjKey(key)) {
      res.push(object[key]);
    }
  });

  return res;
};


參考資料

Extending Types
type guard function doesn't work. type still be judged as string


#TypeScript #extends







Related Posts

[Week8] - 前端串 API

[Week8] - 前端串 API

margin 與 padding 差別在哪裡?(2)

margin 與 padding 差別在哪裡?(2)

[#001] 14. Longest Common Prefix

[#001] 14. Longest Common Prefix


Comments